/*
 * Copyright 2015-2016 Amazon.com, Inc. or its affiliates.  All Rights Reserved.
 *
 * You may not use this file except in compliance with the terms and conditions set forth
 * in the accompanying LICENSE.TXT file.
 *
 * THESE MATERIALS ARE PROVIDED ON AN "AS IS" BASIS.  AMAZON SPECIFICALLY DISCLAIMS, WITH
 * RESPECT TO THESE MATERIALS, ALL WARRANTIES, EXPRESS, IMPLIED, OR STATUTORY, INCLUDING
 * THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
 */

package com.amazon.alexa.voicechrome.internal.views;

import android.animation.Animator;
import android.animation.AnimatorSet;
import android.animation.ObjectAnimator;
import android.content.Context;
import android.graphics.drawable.Animatable;
import android.util.AttributeSet;
import android.util.DisplayMetrics;
import android.view.LayoutInflater;
import android.view.animation.AccelerateInterpolator;

import com.amazon.alexa.voicechrome.R;
import com.amazon.alexa.voicechrome.VoiceChromeVisuals;
import com.amazon.alexa.voicechrome.internal.views.util.wave.AmplitudeView;

public class ListeningView extends ChromeTransitionView implements Animatable {

    AmplitudeView amplitudeView;
    private AmplitudeView amplitudeViewTemp;
    private boolean isRunning;
    private AnimatorSet animatorSet;

    public ListeningView(Context context) {
        super(context);
        initView(context);
    }

    public ListeningView(Context context, AttributeSet attrSet) {
        super(context, attrSet);
        initView(context);
    }

    public ListeningView(Context context, AttributeSet attrSet, int defStyleAttr) {
        super(context, attrSet, defStyleAttr);
        initView(context);
    }

    private void initView(Context context) {
        LayoutInflater.from(context).inflate(R.layout.voicechrome_listening_view, this);
        amplitudeView = (AmplitudeView) findViewById(R.id.amplitude_view);
        // temp view is used to animate from the right to center of the screen when the listening view is shown. We just hide it when the animation is done
        amplitudeViewTemp = (AmplitudeView) findViewById(R.id.amplitude_view_temp);

        DisplayMetrics displayMetrics = getContext().getResources().getDisplayMetrics();
        int deviceWidth = displayMetrics.widthPixels;

        ObjectAnimator leftToCenterAnimator = ObjectAnimator.ofFloat(amplitudeView, TRANSLATION_X, -deviceWidth, 0);

        ObjectAnimator rightToCenterAnimator = ObjectAnimator.ofFloat(amplitudeViewTemp, TRANSLATION_X, deviceWidth, 0);

        ObjectAnimator rightAlphaAnimation = ObjectAnimator.ofFloat(amplitudeViewTemp, ALPHA, 1, 0);
        rightAlphaAnimation.setDuration(150);
        rightAlphaAnimation.setStartDelay(150);

        animatorSet = new AnimatorSet();
        animatorSet.setDuration(300);

        animatorSet.setInterpolator(new AccelerateInterpolator());

        animatorSet.addListener(new Animator.AnimatorListener() {
            @Override
            public void onAnimationStart(Animator animation) {
                amplitudeViewTemp.setAlpha(1);
            }

            @Override
            public void onAnimationEnd(Animator animation) {
            }

            @Override
            public void onAnimationCancel(Animator animation) {
                amplitudeViewTemp.setAlpha(0f);
            }

            @Override
            public void onAnimationRepeat(Animator animation) {

            }
        });

        animatorSet.play(leftToCenterAnimator).with(rightToCenterAnimator).with(rightAlphaAnimation);
        animatorSet.play(leftToCenterAnimator);
    }

    @Override
    public void start() {
        super.start();
        animatorSet.setStartDelay(VoiceChromeVisuals.BOTTOM_LAYER_START_DELAY);
        startIntroAnimation();
    }

    @Override
    public void stop() {
        super.stop();
        animatorSet.cancel();
        isRunning = false;
    }

    @Override
    public void resume() {
        super.resume();
        animatorSet.setStartDelay(0);
        startIntroAnimation();
    }

    @Override
    public void pause() {
        super.pause();
        animatorSet.cancel();
        animatorSet.cancel();
        isRunning = false;
    }

    @Override
    public boolean isRunning() {
        return isRunning;
    }

    private void startIntroAnimation() {
        if(isRunning()) return;
        isRunning = true;
        animatorSet.start();
    }

    /**
     * Updates the Listening state animation with the given volume value.
     *
     * @param volume The signal magnitude metric by which to update the listening animation.
     */
    public void updateAnimation(double volume) {
        amplitudeView.setAmplitude(volume);
    }

    public AmplitudeView getAmplitudeView() {
        return amplitudeView;
    }
}
